package chapter02.part02;

import chapter02.Employee;
import chapter02.FileUtil;

import java.io.*;
import java.time.LocalDate;

/**
 * 随机访问文件 可以移动文件读写指针
 * 
 * 磁盘文件可以随机访问 网络 IO 流不行
 * 
 * 练习将对象写入文件 然后逆序读取
 * 
 * @author insight
 * @since 2021/8/13
 */
public class RandomAccessTest {
    public static void main(String[] args) {
        Employee[] staff = new Employee[3];

        staff[1] = new Employee("mugen",75000,1987,12, 15) ;
        staff[0] = new Employee("jin",60000,1986,10,1) ;
        staff[2] = new Employee("fuu", 40000,1990,3,15) ;

        try (DataOutputStream dos =
                     new DataOutputStream(FileUtil.getTestFileOutputStreamInstance())) {
            writeData(dos, staff);
        } catch (IOException e) {
            e.printStackTrace();
        }
        
        // 使用 RandomAccessFile 读取
        try (RandomAccessFile in = new RandomAccessFile(FileUtil.TEST_FILE_PATH,
                "r")) {
            int n = (int) (in.length() / Employee.RECORD_SIZE);
            Employee[] newStaff = new Employee[n];
            
            // 逆序读取
            for (int i = n - 1; i >= 0; i--) {
                // 使用 seek 移动指针
                in.seek(i * Employee.RECORD_SIZE);
                newStaff[n - 1 - i] = readData(in); 
            }

            for (Employee e : newStaff) {
                System.out.println(e);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void writeData(DataOutput out, Employee[] employees) throws IOException {
        for (Employee e : employees) {
            writeFixedString(e.getName(), Employee.NAME_SIZE, out);
            out.writeDouble(e.getSalary());

            LocalDate hireDay = e.getHireDay();
            out.writeInt(hireDay.getYear());
            out.writeInt(hireDay.getMonthValue());
            out.writeInt(hireDay.getDayOfMonth());
        }
    }

    public static Employee readData(DataInput in) throws IOException {
        String name = readFixedString(Employee.NAME_SIZE, in);
        double s = in.readDouble();
        int y = in.readInt();
        int m = in.readInt();
        int d = in.readInt();
        return new Employee(name, s, y, m, d);
    }

    private static void writeFixedString(String name, int size, DataOutput out) throws IOException {
        // 用0补齐
        for (int i = 0; i < size; ++i) {
            out.writeChar(i < name.length() ? name.charAt(i) : 0);
        }
    }

    private static String readFixedString(int size, DataInput in) throws IOException {
        StringBuilder sb = new StringBuilder(size);
        for (int i = 0; i < size; ++i) {
            char c = in.readChar();
            if (c == 0) break;
            sb.append(c);
        }
        // 跳过剩余的0字符 因为读取了一个0字符 所以减一
        in.skipBytes((size - sb.length() - 1) * 2);
        return sb.toString();
    }
}